<?php
namespace jy_aliesign;
defined('BY_JYA') or exit('error');
class api extends \plugin{
	public function __construct($setting=array()){
		parent::__construct('jy_aliesign');
		$setting=plugin('jy_aliesign')->plugin_setting('basic');
		if(!$setting['appid']){
			exi('请设置E签宝应用ID!','error');
		}
		if(!$setting['secret']){
			exi('请设置E签宝应用密钥!','error');
		}
		$this->appid=$setting['appid'];
		$this->secret=$setting['secret'];
		$this->signer2_sealid=$setting['signer2_sealid'];
		$this->apiurl=$setting['isdemo']?'https://smlopenapi.esign.cn':'https://openapi.esign.cn';
	}
	public function request($post,$url=''){
		$post=$post?ijson_encode($post):'';
		$projectScert=$this->secret;
		$contentMd5=$this->getBodyContentMD5($post);
		$url2=$this->querySort($url);
		$type=$post?'POST':'GET';
		$signdata=$this->getSignature($projectScert,$type,"*/*",'application/json; charset=UTF-8',$contentMd5,'','',$url2);
		$extra=array(
			'X-Tsign-Open-App-Id' =>$this->appid,
			'X-Tsign-Open-Auth-Mode'=> 'Signature',
			'X-Tsign-Open-Ca-Signature'=>$signdata,
			'X-Tsign-Open-Ca-Timestamp'=>$this->getMillisecond(),
			'Accept' =>'*/*',
			'Content-Type' => 'application/json; charset=UTF-8',
			'Content-MD5'=>$contentMd5,
		);
		//file_put_contents(ROOT_D.'/addons/jy_aliesign/error_log.txt',date('YmdHis').'~~'.$url."~~~~~~~~\n",FILE_APPEND);
		//file_put_contents(ROOT_D.'/addons/jy_aliesign/error_log.txt',date('YmdHis').'~~'.$post."~~~~~~~~\n",FILE_APPEND);
		$res=cfc('http')->ihttp_request($this->apiurl.$url,$post,$extra);
		if(is_error($res)){
			exi($res['message'].'，请求异常！','error');
		}
		if($res['code'] && !$res['content']){
			exi($res['code'].'，内容为空！请在真机上体验！','error');
		}
		$res=json_decode($res['content'],true);
		if($res['code']){
			exi($res['message'].'，请求异常！','error');
		}
		return $res['data'];
	}
	/*
		获取签署流程ID
	*/
	//E签宝api文档:https://open.esign.cn/doc/opendoc/pdf-sign3/nxhgcl3bfgqz8qlz
	//E签宝文档：https://opendocs.alipay.com/open/00pq4d?pathHash=d1c8ace8
	public function ehtong_signflows_create($params){
		$paylog = pdo_get('core_paylog',array('tid'=>$params['ordersn'],'uniacid'=>$_SESSION['uniacid']));
		$fans=pdo_get('core_fans',array('mid'=>$paylog['mid'],'uniacid'=>$_SESSION['uniacid']));
		$openid = $fans['openid'];
		//创建合同
		$params['mid']=$paylog['mid'];
		$signer1_2 = $this->ehtong_signflows_templates($params);
		$getpdf = $this->ehtong_signflows_fileid($params);
		$realname=pdo_getcolumn('core_members',array('id'=>$paylog['mid'],'uniacid'=>$_SESSION['uniacid']),'realname');
		$cardnum=pdo_getcolumn('core_members',array('id'=>$paylog['mid'],'uniacid'=>$_SESSION['uniacid']),'cardnum');
		$mobile=pdo_getcolumn('core_members',array('id'=>$paylog['mid'],'uniacid'=>$_SESSION['uniacid']),'mobile');
		if(!$mobile){
		   exi('请先实名认证，并填写手机号！','error'); 
		}
		$psnInfo = [
			'psnName'=>$realname?:'未知姓名',
			'psnIDCardNum'=>$cardnum,
			'psnIDCardType'=>'CRED_PSN_CH_IDCARD',
		];
		$signFieldPosition = array(
			'positionX'=>$signer1_2['signer1']['componentPosition']['componentPositionX'],
			'positionY'=>$signer1_2['signer1']['componentPosition']['componentPositionY'],
			'positionPage'=>$signer1_2['signer1']['componentPosition']['componentPageNum'],
		);
		$normalSignFieldConfig = array(
			'freeMode'=>false,
			'autoSign'=>false,
			'signFieldStyle'=>1,
			'psnSealStyles'=>2,
			'signFieldWidth'=>$signer1_2['signer1']['componentSize']['componentWidth'],
			'signFieldHeight'=>$signer1_2['signer1']['componentSize']['componentHeight'],
			'signFieldPosition'=>$signFieldPosition,
		);
		$signDateConfig=array(
			'showSignDate'=>1
		);
		$signFields = array(
			'fileId'=>$getpdf['fileId'],
			'customBizNum'=>$params['ordersn'],
			'normalSignFieldConfig'=>$normalSignFieldConfig,
			'signDateConfig'=>$signDateConfig
		);
		$psnSignerInfo = array(
			'psnAccount'=>$mobile,
			'psnInfo'=>$psnInfo,
		);
		//个人
		$signers[]=array(
			'signerType'=>0,
			'psnSignerInfo'=>$psnSignerInfo,
			'signFields'=>array($signFields),
		);
		//企业自动签署
		$signFieldPosition = array(
			'positionX'=>$signer1_2['signer2']['componentPosition']['componentPositionX'],
			'positionY'=>$signer1_2['signer2']['componentPosition']['componentPositionY'],
			'positionPage'=>$signer1_2['signer2']['componentPosition']['componentPageNum'],
		);
		$normalSignFieldConfig = array(
			'freeMode'=>false,
			'autoSign'=>true,
			'signFieldStyle'=>1,
			'signFieldWidth'=>$signer1_2['signer2']['componentSize']['componentWidth'],
			'signFieldHeight'=>$signer1_2['signer2']['componentSize']['componentHeight'],
			'signFieldPosition'=>$signFieldPosition,
		);
		if($this->signer2_sealid){
			$normalSignFieldConfig['assignedSealId']=$this->signer2_sealid;
		}
		$signFields = array(
			'fileId'=>$getpdf['fileId'],
			'customBizNum'=>$params['ordersn'],
			'normalSignFieldConfig'=>$normalSignFieldConfig,
			'signFieldPosition'=>$signFieldPosition,
		);
		$orgSignerInfo = array(
			'psnAccount'=>$mobile,
			'psnInfo'=>$psnInfo,
		);
		$signers[]=array(
			'signerType'=>1,
			'orgSignerInfo'=>$orgSignerInfo,
			'signFields'=>array($signFields),
		);
		$signFlowConfig = array(
			'signFlowTitle'=>'租赁交付单',
			'autoFinish'=>true,
			'notifyUrl'=>SITEROOT .'addons/jy_aliesign/notify.php',
			'redirectConfig'=>array('redirectUrl'=>'wechat://back'),
			'signConfig'=>array('availableSignClientTypes'=>1,'showBatchDropSealButton'=>true)
		);
		$object['docs'] = array(
			array(
				'fileId'=>$getpdf['fileId'],
			)
		);
		$object['signFlowConfig'] = $signFlowConfig;
		$object['signers'] = $signers;
		$json = ijson_encode($object);
		$url='/v3/sign-flow/create-by-file';
		$result = $this->request($json,$url);
		if(!$result['signFlowId']){
			return ['code'=>0,'msg'=>$result['sub_msg']];
		}
		$flow_id = $result['signFlowId'];
		$params['flow_id']=$flow_id;
		$urlinfo = $this->ehtong_signflows_url($params);
		model('jy_aliesign/model')->signlog($paylog,$flow_id);
		return array('code'=>1,'flow_id'=>$flow_id,'isapi'=>1,'shorturl'=>$urlinfo['shortUrl'],'url'=>$urlinfo['url']);
	}
	//https://open.esign.cn/doc/opendoc/pdf-sign3/aoq509
	public function ehtong_signflows_templates($params){
		$url='/v3/doc-templates/'.$params['esigntpid'];
		$result = $this->request('',$url);
		if(!$result['components']){
			exi('获取控件详情失败！','error');
		}
		if($result['components']){
			foreach($result['components'] as $item){
				if($item['componentKey']=='signer1'){
					$signer1=$item;
				}
				if($item['componentKey']=='signer2'){
					$signer2=$item;
				}
			}
		}
		return array('signer1'=>$signer1,'signer2'=>$signer2);
	}
	//https://open.esign.cn/doc/opendoc/pdf-sign3/mv8a3i
	public function ehtong_signflows_fileid($params){
		$paylog = pdo_get('core_paylog',array('tid'=>$params['ordersn'],'uniacid'=>$_SESSION['uniacid']));
		$mobile=pdo_getcolumn('core_members',array('id'=>$params['mid'],'uniacid'=>$_SESSION['uniacid']),'mobile');
		if(!$mobile){
		   exi('请先实名认证，并填写手机号！','error'); 
		}
		$object=array();
		$object['docTemplateId'] = $params['esigntpid'];
		$object['fileName'] = '租赁交付单'.$params['ordersn'];
		$components = $this->get_esign_fill_contents($paylog['oid']);
		$object['components'] =$components;
		$json = ijson_encode($object);
		$url='/v3/files/create-by-doc-template';
		$result = $this->request($json,$url);
		if(!$result['fileId']){
			exi('获取签约合同失败！','error');
		}
		if($result['fileDownloadUrl']){
			//保存合同
			$ext=substr(strrchr($result['fileDownloadUrl'],'.'),1);
			$docsstr=@file_get_contents($result['fileDownloadUrl']);
			$file_hash=hash("sha256", $docsstr);
			$file_url=cfc('files')->source_save($docsstr,'other',$ext);
			$result['file_url']=$file_url;
			$result['file_hash']=$file_hash;
		}
		return $result;
	}
	//https://open.esign.cn/doc/opendoc/pdf-sign3/pvfkwd
	public function ehtong_signflows_url($params){
	    $mobile=pdo_getcolumn('core_members',array('id'=>$params['mid'],'uniacid'=>$_SESSION['uniacid']),'mobile');
		if(!$mobile){
		   exi('请先实名认证，并填写手机号！','error'); 
		}
		$object=array();
		$object['signFlowId'] = $params['flow_id'];
		$object['urlType'] = 2;
		$operator=array(
			'psnAccount'=>$mobile,
		);
		$object['operator'] =$operator;
		$json = ijson_encode($object);
		$url='/v3/sign-flow/'.$params['flow_id'].'/sign-url';
		$result = $this->request($json,$url);
		if(!$result['shortUrl'] && !$result['url']){
			exi('获取签约地址失败！','error');
		}
		return $result;
	}
	public function get_esign_fill_contents($order_id){
		$order=pdo_get('jy_weishop_order',array('id'=>$order_id,'uniacid'=>$_SESSION['uniacid']));
		$api_data=json_decode($order['api_data'],true);
		$allqi = $api_data['allqi'];
		$order['api_data'] = $api_data;
		$address=pdo_get('core_address',array('id'=>$order['addressid'],'uniacid'=>$_SESSION['uniacid']));
		$pcd = json_decode($address['pcd'],true);
		$addressinfo =$pcd['province'].$pcd['city'].$pcd['district'].$address['address'];
		$cardnum=pdo_getcolumn('core_members',array('id'=>$order['mid'],'uniacid'=>$_SESSION['uniacid']),'cardnum');
		$realname=pdo_getcolumn('core_members',array('id'=>$order['mid'],'uniacid'=>$_SESSION['uniacid']),'realname');
		if(!$cardnum || !$realname){
		   	exi('请先实名认证！身份证号码为空','error'); 
		}
		$data[] = array('componentKey'=>'name','componentValue'=>$realname);
		$data[] = array('componentKey'=>'code','componentValue'=>$cardnum);
		$data[] = array('componentKey'=>'mobile','componentValue'=>$address['mobile']);
		$data[] = array('componentKey'=>'address','componentValue'=>$addressinfo);
		$data[] = array('componentKey'=>'email','componentValue'=>'');
		$data[] = array('componentKey'=>'order_sn','componentValue'=>$order['ordersn']);
		//$data[] = array('componentKey'=>'order_sn2','componentValue'=>$order['ordersn']);
		$order_goods = pdo_get('jy_weishop_order_goods',array('orderid'=>$order['id'],'uniacid'=>$_SESSION['uniacid']));
		$specs=pdo_getcolumn('jy_weishop_goods_option',array('id'=>$order_goods['optionid'],'uniacid'=>$_SESSION['uniacid']),'specs');
		$specs=explode("_",$specs);
		foreach($specs as &$spec){
			$spec=pdo_getcolumn('jy_weishop_goods_spec_item',array('id'=>$spec,'uniacid'=>$_SESSION['uniacid']),'title');
		}
		$goods_optiontitle=implode("，",$specs);
		$goods = pdo_get('jy_weishop_goods',array('id'=>$order_goods['goodsid'],'uniacid'=>$_SESSION['uniacid']));	
		$goods_brand=pdo_getcolumn('jy_weishop_goods_group',array('id'=>$goods['pcate'],'uniacid'=>$_SESSION['uniacid']),'title');
		//$goodstitle=cfc('tools')->substr($goods['title'],0,50);
		$goodstitle=$goods['title'];
		$data[] = array('componentKey'=>'goods_name','componentValue'=>$goodstitle);
		$data[] = array('componentKey'=>'taocan_name','componentValue'=>$goods_optiontitle);
		$data[] = array('componentKey'=>'goods_desc','componentValue'=>$goods['title']);
		$data[] = array('componentKey'=>'goods_brand','componentValue'=>$goods_brand?:'无');
		$data[] = array('componentKey'=>'goods_optiontitle','componentValue'=>$goods_optiontitle);
		$data[] = array('componentKey'=>'goods_total','componentValue'=>$order_goods['total']);
		$data[] = array('componentKey'=>'goods_totalzu','componentValue'=>$api_data['allprice']);
		//$data[] = array('componentKey'=>'goods_danzu','componentValue'=>$api_data['price']);
		$data[] = array('componentKey'=>'goods_price','componentValue'=>$order['goodsprice']);
		//$data[] = array('componentKey'=>'goods_duan','componentValue'=>$order['goodsprice']);
		$data[] = array('componentKey'=>'zuqi','componentValue'=>$api_data['allqi']);
		//$data[] = array('componentKey'=>'jia_mobile','componentValue'=>$_SESSION['account']['phone']);
		//$data[] = array('componentKey'=>'jia_name','componentValue'=>$_SESSION['account']['cname']);
		//$data[] = array('componentKey'=>'jia2_name','componentValue'=>$_SESSION['account']['cname']);
		//$data[] = array('componentKey'=>'jia_address','componentValue'=>$_SESSION['account']['address']);
		//$data[] = array('componentKey'=>'fangshi','componentValue'=>'分期租赁');
		$data[] = array('componentKey'=>'jsyafee','componentValue'=>'0');
		//合同编号
		$jy_aliesign=plugin('jy_aliesign')->plugin_setting('basic');
		$nonce = random(2,true);
		$pre=$jy_aliesign['hetongper']?:'HT';
		$hetongsn=$pre.date('YmdHis').$nonce;
		$data[] = array('componentKey'=>'hetongsn','componentValue'=>$hetongsn);
		$basic=$this->plugin_setting('basic');
		$qinum=$basic['qinum']?:12;
		$starttime=strtotime($order['api_data']['starttime']);
		for($i=1;$i<=$qinum;$i++){
			$data[]=array('componentKey'=>'zqkey'.$i,'componentValue'=>'第'.$i.'期');
			$day=$starttime+30*($i-1)*24*3600;
			$day=date('Y-m-d',$day);
			$data[]=array('componentKey'=>'zjkey'.$i,'componentValue'=>$order['api_data']['total_price']?:'无');
			$data[]=array('componentKey'=>'zjfkey'.$i,'componentValue'=>$day);
			$data[]=array('componentKey'=>'mdkey'.$i,'componentValue'=>$order['api_data']['duan_price']?:'无');
		}
		return $data;
	}
	/**
     * 生成签名
     * @param $projectScert
     * @param $httpMethod
     * @param $accept
     * @param $contentType
     * @param $contentMd5
     * @param $date
     * @param $headers
     * @param $url
     * @return string
     */
    public static function getSignature($projectScert,$httpMethod,$accept,$contentType,$contentMd5,$date,$headers,$url){

        $stringToSign = $httpMethod . "\n" . $accept . "\n"  . $contentMd5 . "\n" . $contentType . "\n"  . $date . "\n" .$headers  ;
        if($headers != ''){
            $stringToSign .= "\n".$url;
        }else{
            $stringToSign .= $url;
        }
        //$stringToSign=$this->printMsg($stringToSign);
        $signature = hash_hmac("sha256",$stringToSign, $projectScert, true);
        $signature = base64_encode($signature);
        return $signature;
    }
	static function  printMsg($msg)
    {
        $stringToSign= "<pre/>";
        if (is_array($msg) || is_object($msg)) {
           $msg= var_dump($msg);
        } else {
           $msg= $msg . "\n";
        }
		$stringToSign .=$msg;
		return $stringToSign;
    }
	static function getBodyContentMD5($bodyData){
		//计算Body体的Content-MD5
		$md5Bytes = md5($bodyData,true);
		$contentMD5 = base64_encode($md5Bytes);
		return $contentMD5;
	}
	public static function querySort($url,$isEncode=false){
        #存在query参数
        if (!strpos($url, "?") === false) {
            $query_arr = [];
            $url_path = substr($url, 0, strpos($url, "?"));
            $url_query = substr($url, strpos($url, "?") + 1, mb_strlen($url));
            parse_str($url_query, $query_arr);
            ksort($query_arr);
            //reset()内部指针指向数组中的第一个元素
            reset($query_arr);
            $query_str = http_build_query($query_arr);
            if(!$isEncode){
                $query_str = urldecode($query_str);
            }
            $url = $url_path . '?' . $query_str;
            return $url;
        }
        return $url;
    }
	 /**
     * 生成13位时间戳
     * @return float
     */
    public static function getMillisecond() {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f',(floatval($t1)+floatval($t2))*1000);
    }
}